﻿using Rsdn.Janus.Core.Extensibility;

namespace Rsdn.Janus
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.IO;
    using System.Reflection;
    using System.Xml;
    using System.Xml.Schema;
    using Database;
    using SmartApp;

    /// <summary>
    /// Обеспечивает базовую функциональность ядра системы.
    /// </summary>
    internal class JanusHost : IServiceProvider, IDisposable, ISupportInitialize
    {
        private readonly ServiceManager _serviceManager;
        private readonly IActivePartManager _activePartManager;

        internal JanusHost(IServiceProvider serviceProvider)
        {
            _serviceManager =
                serviceProvider == null
                    ? new ServiceManager(true)
                    : new ServiceManager(true, serviceProvider);

            // TODO: Hack! Must be eliminated.
            ApplicationManager.Instance.ServiceProvider = this;

            _serviceManager.PublishDisposable<IEventBroker>(new EventBroker());
            InitExtensibility();
            _activePartManager = ActivePartsHelper.CreateAndPublishManager(_serviceManager);

        }


        private void InitExtensibility()
        {
            var asmHelper = new AssemblyScanHelper();

            // Добавляем собственную сборку
            asmHelper.AddAssembly(GetType().Assembly);
            // Добавляем Janus-Common
            asmHelper.AddAssembly(typeof(ExtensionInfoProviderBase).Assembly);
            // Добавляем сборки всех расширений
            IEnumerable<ExtensionLoadInfo> extensionAssemblies =
                JanusExtensionManager.GetExtensionAssemblies(GetType(), EnvironmentHelper.GetJanusRootDir(), false);

            foreach (ExtensionLoadInfo loadInfo in extensionAssemblies)
            {
                asmHelper.AddAssembly(Assembly.LoadFrom(loadInfo.ExtensionFullName));
                Trace.WriteLine("Use extension assembly '{0}'".FormatStr(loadInfo.ExtensionFullName));
            }

            var extensionManager = new ExtensionManager(_serviceManager);
            StrategyFactoryStrategy.RegisterAndScan(
                _serviceManager,
                extensionManager,
                asmHelper.GetTypes());
        }

        #region IServiceProvider Members

        public object GetService(Type serviceType)
        {
            return _serviceManager.GetService(serviceType);
        }

        #endregion

        #region Implementation of IDisposable
        public void Dispose()
        {
            _serviceManager.Dispose();
        }
        #endregion

        #region Implementation of ISupportInitialize
        public void BeginInit()
        {
        }

        public void EndInit()
        {
            IForumQueryService forumQueryService = _serviceManager.GetRequiredService<IForumQueryService>();
            forumQueryService.StoreForumLastUpdateDate();
            _activePartManager.Activate();

        }
        #endregion
    }
}
